package com.koron.standard.jobStock.overhaul.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koron.common.core.business.datadict.utils.DataDictTool;
import com.koron.standard.bean.query.PageQuery;
import com.koron.standard.jobStock.overhaul.bean.dto.OverhaulDTO;
import com.koron.standard.jobStock.overhaul.bean.dto.OverhaulItemDTO;
import com.koron.standard.jobStock.overhaul.bean.dto.OverhaulMajorDTO;
import com.koron.standard.jobStock.overhaul.bean.po.Overhaul;
import com.koron.standard.jobStock.overhaul.bean.po.OverhaulReady;
import com.koron.standard.jobStock.overhaul.bean.query.OverhaulQuery;
import com.koron.standard.jobStock.overhaul.bean.vo.OverhaulVO;
import com.koron.standard.jobStock.overhaul.mapper.OverhaulMapper;
import com.koron.standard.utils.CommonUtils;
import com.koron.standard.utils.StandardCodeTools;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 大修标准信息(Overhaul)表服务实现类
 *
 * @author jzp
 * @since 2021-09-16
 */
@Service
public class OverhaulService extends ServiceImpl<OverhaulMapper, Overhaul> {

    @Autowired
    private OverhaulItemService overhaulItemService;

    @Autowired
    private OverhaulReadyService overhaulReadyService;

    public QueryWrapper<OverhaulVO> queryWrapper(OverhaulQuery query) {
        // 设置默认只查有权限的水司数据
        query.setAppids(CommonUtils.getDefaultAppids(query.getAppids()));
        query.setPublicStatus(CommonUtils.getDefaultPublicStatus(query.getPublicStatus()));

        QueryWrapper<OverhaulVO> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotEmpty(query.getCode()), "c_overhaul.code", query.getCode());
        wrapper.like(StrUtil.isNotEmpty(query.getName()), "c_overhaul.name", query.getName());
        wrapper.eq(StrUtil.isNotEmpty(query.getTypeId()), "c_overhaul.type_id", query.getTypeId());
        wrapper.like(StrUtil.isNotEmpty(query.getTypeName()), "c_type.name", query.getTypeName());

        if (query.getPublicStatus() != null && query.getPublicStatus() > 0) {
            // 如果是共有的
            wrapper.and(w -> w.eq("c_overhaul.public_status", query.getPublicStatus())
                    .or(CollUtil.isNotEmpty(query.getAppids()))
                    .in(CollUtil.isNotEmpty(query.getAppids()), "c_overhaul.appid", query.getAppids()));
        } else {
            wrapper.in(CollUtil.isNotEmpty(query.getAppids()), "c_overhaul.appid", query.getAppids());
        }

        wrapper.eq(StrUtil.isNotEmpty(query.getDeptId()), "c_overhaul.dept_id", query.getDeptId());
        wrapper.like(StrUtil.isNotEmpty(query.getDeptName()), "c_overhaul.dept_name", query.getDeptName());
        wrapper.eq(query.getStatus()!=null, "c_overhaul.status", query.getStatus());
        wrapper.eq(StrUtil.isNotEmpty(query.getScale()), "c_overhaul.scale", query.getScale());
        wrapper.eq(StrUtil.isNotEmpty(query.getMajor()), "c_overhaul.major", query.getMajor());
        if (CollUtil.isNotEmpty(query.getDates())) {
            wrapper.between("c_overhaul.create_time", query.getDates().get(0), query.getDates().get(1));
        }
        wrapper.eq("c_overhaul.delete_flag", 0);
        return wrapper;
    }


    public Page<OverhaulVO> page(PageQuery<OverhaulVO> pageQuery, OverhaulQuery query) {
        QueryWrapper<OverhaulVO> wrapper = queryWrapper(query);

        Page<OverhaulVO> page = pageQuery.convertPage();
        List<OrderItem> orders = pageQuery.getOrders();
        for (OrderItem order : orders) {
            if (order.getColumn().equals("type_name")) {
                order.setColumn("c_type.name");
            } else if (order.getColumn().equals("app_name")) {
                order.setColumn("s_app.name");
            } else {
                order.setColumn("c_overhaul." + order.getColumn());
            }
        }
        getBaseMapper().selectPageVo(page, wrapper);
        return page;
    }

    public List<OverhaulMajorDTO> listDto(OverhaulQuery query) {
        QueryWrapper<OverhaulVO> wrapper = queryWrapper(query);
        List<OverhaulVO> overhaulVOS = getBaseMapper().selectPageVo(wrapper);
        List<OverhaulDTO> overhaulDTOS = overhaulVOS.stream().map(vo -> getDtoById(vo.getId())).collect(Collectors.toList());
        Map<String, List<OverhaulDTO>> majorMap = overhaulDTOS.stream().collect(Collectors.groupingBy(OverhaulDTO::getMajor));
        List<OverhaulMajorDTO> majors = new ArrayList<>();
        Map<String, String> majorKV = DataDictTool.getDataDictByCode("publicDictionary", "common_major");
        majorMap.forEach((key, value) -> {
            OverhaulMajorDTO dto = new OverhaulMajorDTO();
            dto.setMajor(key);
            dto.setMajorName(majorKV.get(key));
            dto.setForms(value);
            majors.add(dto);
            majors.stream().forEach(major -> {
                List<OverhaulDTO> forms = major.getForms();
                if(CollUtil.isEmpty(forms)) {
                    return;
                }
                forms.stream().forEach(form -> form.setStandardId(form.getId()));
            });
        });
        return JSONArray.parseArray(JSON.toJSONString(majors), OverhaulMajorDTO.class);
    }

    public OverhaulDTO getDtoById(String id) {
        OverhaulDTO overhaulDTO = new OverhaulDTO();
        // 1. 查询基本信息
        OverhaulVO overhaulVO = getBaseMapper().getVoById(id);
        BeanUtils.copyProperties(overhaulVO, overhaulDTO);

        // 2. 查询作业项目信息
        List<OverhaulItemDTO> overhaulItemDTOs = overhaulItemService.getTreeByOverhaulId(id);
        overhaulDTO.setItemDTOs(overhaulItemDTOs);

        // 3. 查询作业准备信息
        List<OverhaulReady> overhaulReadies = overhaulReadyService.listByOverhaulId(id);
        overhaulDTO.setOverhaulReadies(overhaulReadies);

        return overhaulDTO;
    }

    /**
     * 筛选除有标准的分类id
     */
    public List<String> filterTypeIds(List<String> typeIds) {
        LambdaQueryWrapper<Overhaul> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CollUtil.isNotEmpty(typeIds), Overhaul::getTypeId, typeIds);
        List<Overhaul> list = list(wrapper);
        return list.stream().map(Overhaul::getTypeId).distinct().collect(Collectors.toList());
    }

    public void saveDto(OverhaulDTO overhaulDTO) {
        // 设置编码
        overhaulDTO.setCode(StandardCodeTools.getOverhaulJobCode());

        // 默认草稿
        overhaulDTO.setStatus(0);

        // 保存
        updateDtoById(overhaulDTO);

    }

    @Transactional(rollbackFor = RuntimeException.class)
    public void updateDtoById(OverhaulDTO overhaulDTO) {
        // 1. 删除所有子项-日常维护标准下作业项目树
        overhaulItemService.removeByOverhaulId(overhaulDTO.getId());

        // 2. 删除所有作业准备
        overhaulReadyService.removeByOverhaulId(overhaulDTO.getId());

        // 3. 保存或更新基本信息
        saveOrUpdate(overhaulDTO);

        // 4. 保存节点信息
        List<OverhaulItemDTO> overhaulItemDTOs = Optional.ofNullable(overhaulDTO.getItemDTOs()).orElse(new ArrayList<>());
        for (OverhaulItemDTO overhaulItemDTO : overhaulItemDTOs) {
            overhaulItemDTO.setOverhaulId(overhaulDTO.getId());
            overhaulItemService.saveRootDto(overhaulItemDTO); // 会递归保存所有子节点信息
        }

        // 5. 保存作业准备信息
        List<OverhaulReady> overhaulReadies = Optional.ofNullable(overhaulDTO.getOverhaulReadies()).orElse(new ArrayList<>());
        for (OverhaulReady overhaulReady : overhaulReadies) {
            overhaulReady.setOverhaulId(overhaulDTO.getId());
        }
        overhaulReadyService.saveBatch(overhaulReadies);

    }

    public void updateToPublic(List<String> ids) {
        List<Overhaul> overhauls = new ArrayList<>();
        for (String id : ids) {
            Overhaul overhaul = new Overhaul();
            overhaul.setId(id);
            overhaul.setPublicStatus(1);
            overhauls.add(overhaul);
        }
        updateBatchById(overhauls);
    }

    public void updateStatus(String id, Integer status) {
        LambdaUpdateWrapper<Overhaul> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Overhaul::getId, id);
        wrapper.set(Overhaul::getStatus, status);
        update(wrapper);
    }

}
